package com.firexxx.study.proxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @description: TODO
 * @author: zhuangzhang2
 * @date: 2021-02-05 10:01
 */
public class Main {

    interface ISing {
        void sing();
        void dance();
    }

    interface IActor {
        void acting();
    }

    static class LDHStar implements ISing, IActor {
        @Override
        public void sing() {
            System.out.println("刘德华唱歌");
        }

        @Override
        public void dance() {
            System.out.println("刘德华跳舞");
        }

        @Override
        public void acting() {
            System.out.println("刘德华演戏");
        }
    }

    static class DogUtils{
        public static void method1() {
            System.out.println("增强方式一");
        }

        public static void method2() {
            System.out.println("增强方式二");
        }
    }

    static class ProxyInvocationHandle implements InvocationHandler {
        private Object target;

        public void setTarget(Object target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            DogUtils.method1();
            method.invoke(target, args);
            DogUtils.method2();
            return null;
        }
    }

    static class MyProxyFactory{
        public static Object getProxy(Object target) {
            ProxyInvocationHandle handle = new ProxyInvocationHandle ();
            handle.setTarget(target);
            Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handle);
            return proxy;
        }
    }

    public static void main(String[] args) {
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

        ISing star = new LDHStar();
        ISing proxy =(ISing) MyProxyFactory.getProxy(star);
        proxy.sing();
        proxy.dance();

        ((IActor)proxy).acting();
    }

}
